﻿using System;
using System.IO;
using System.Security.Cryptography;
using System.Text;

// namespace Singbon.Key
namespace SingbonDES
{
  public class Md5Des2
  {
    //默认密钥向量
    private static readonly byte[] Keys = { 0x12, 0x34, 0x56, 0x78, 0x90, 0xAB, 0xCD, 0xEF };

    /// <summary>
    /// DES加密字符串
    /// </summary>
    /// <param name="encryptString">待加密的字符串</param>
    /// <param name="encryptKey">加密密钥,要求为8位</param>
    /// <returns>加密成功返回加密后的字符串，失败返回源串</returns>
    public static string EncryptDes(string encryptString, string encryptKey)
    {
      try
      {
        byte[] rgbKey = Encoding.UTF8.GetBytes(encryptKey.Substring(0, 8));
        byte[] rgbIv = Keys;
        byte[] inputByteArray = Encoding.UTF8.GetBytes(encryptString);
        DESCryptoServiceProvider dCsp = new DESCryptoServiceProvider();
        MemoryStream mStream = new MemoryStream();
        CryptoStream cStream =
          new CryptoStream(mStream, dCsp.CreateEncryptor(rgbKey, rgbIv), CryptoStreamMode.Write);
        cStream.Write(inputByteArray, 0, inputByteArray.Length);
        cStream.FlushFinalBlock();
        return Convert.ToBase64String(mStream.ToArray());
      }
      catch
      {
        return encryptString;
      }
    }

    /// <summary>
    /// DES解密字符串
    /// </summary>
    /// <param name="decryptString">待解密的字符串</param>
    /// <param name="decryptKey">解密密钥,要求为8位,和加密密钥相同</param>
    /// <returns>解密成功返回解密后的字符串，失败返源串</returns>
    public static string DecryptDes(string decryptString, string decryptKey)
    {
      try
      {
        byte[] rgbKey = Encoding.UTF8.GetBytes(decryptKey);
        byte[] rgbIv = Keys;
        byte[] inputByteArray = Convert.FromBase64String(decryptString);
        DESCryptoServiceProvider dcsp = new DESCryptoServiceProvider();
        MemoryStream mStream = new MemoryStream();
        CryptoStream cStream = new CryptoStream(mStream, dcsp.CreateDecryptor(rgbKey, rgbIv), CryptoStreamMode.Write);
        cStream.Write(inputByteArray, 0, inputByteArray.Length);
        cStream.FlushFinalBlock();
        Console.WriteLine(@"解密:" + Encoding.UTF8.GetString(mStream.ToArray()));
        return Encoding.UTF8.GetString(mStream.ToArray());
      }
      catch
      {
        return decryptString;
      }
    }


    /// <summary>
    /// 功能：    MD5加密类
    /// 用于数据库内职员和客户密码的生成
    /// </summary>
    /// <param name="strEncrypt">未加密的字符串</param>
    /// <param name="strEncrypted">加密过的字符串</param>
    public static void Md5Encrypt(string strEncrypt, out string strEncrypted)
    {
      try
      {
        if (strEncrypt == null)
          strEncrypt = "";
        //由于md5算法是公开的，并且我们系统客户和职员的密码都是数字，且
        //都不超过6位，如果知道库里密码很容易被使用穹举法算出原始密码，所以对密码进行了稍微的变化
        //strEncrypt="Nwa20"+strEncrypt+"eCp06";
        MD5CryptoServiceProvider oMd5 = new MD5CryptoServiceProvider();
        byte[] bytesEncrypt = Encoding.Default.GetBytes(strEncrypt);
        byte[] bytesEncrypted = oMd5.ComputeHash(bytesEncrypt, 0, bytesEncrypt.Length);
        strEncrypted = "";
        for (int i = 0; i < bytesEncrypted.Length; i++)
        {
          strEncrypted += bytesEncrypted[i].ToString("x").PadLeft(2, '0');
        }
      }
      catch (Exception ex)
      {
        throw new Exception(ex.Message);
      }
    }


    // <summary>
    /// 加密原函数
    /// <param name="src"></param>
    /// <param name="sKey"></param>
    /// <returns></returns>
    public static byte[] DesEncrypt(byte[] src, string sKey)
    {
      try
      {
        if (src == null || sKey == null || sKey.Length != 8)
        {
          return null;
        }

        DESCryptoServiceProvider des = new DESCryptoServiceProvider();
        // byte[] x = Encoding.ASCII.GetBytes(sKey)
        des.Key = Encoding.ASCII.GetBytes(sKey);
        des.IV = Encoding.ASCII.GetBytes(sKey);
        MemoryStream ms = new MemoryStream();
        CryptoStream cs = new CryptoStream(ms, des.CreateEncryptor(), CryptoStreamMode.Write);
        cs.Write(src, 0, src.Length);
        cs.FlushFinalBlock();
        return ms.ToArray();
      }
      catch
      {
        return null;
      }
    }

    /// <summary>
    /// 解密原函数
    /// </summary>
    /// <param name="src"></param>
    /// <param name="sKey"></param>
    /// <returns></returns>
    public static byte[] DesDecrypt(byte[] src, string sKey)
    {
      try
      {
        if (src == null || sKey == null || sKey.Length != 8)
        {
          return null;
        }

        DESCryptoServiceProvider des = new DESCryptoServiceProvider();
        des.Key = Encoding.ASCII.GetBytes(sKey);
        des.IV = Encoding.ASCII.GetBytes(sKey);
        MemoryStream ms = new MemoryStream();
        CryptoStream cs = new CryptoStream(ms, des.CreateDecryptor(), CryptoStreamMode.Write);
        cs.Write(src, 0, src.Length);
        cs.FlushFinalBlock();
        StringBuilder ret = new StringBuilder();
        Console.WriteLine(@"ret:" + ret);
        return ms.ToArray();
      }
      catch
      {
        return null;
      }
    }
  }
}